package com.sgs.soda.core.auth;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author tianzhonghai
 * @date 2020/5/17 7:52 PM
 */

@Component
public class JwtTokenService {
    private static final String CLAIM_KEY_USERID = "sub";

    @Value("${jwt.secret:mySecret}")
    private String secret;

    @Value("${jwt.header:Authorization}")
    private String jwtHeader;

    @Value("${jwt.tokenType:Bearer }")
    private String tokenType;

    public String generateToken(JwtUserDetail jwtUserDetail){
        //默认7200秒
        return generateToken(jwtUserDetail, 30 * 24 * 3600 * 1000);
    }

    public String generateToken(JwtUserDetail jwtUserDetail,long expireIn){
        Map<String, Object> claims = new HashMap<>();
        //claims.put(CLAIM_KEY_NICKNAME, jwtUserDetail.getNickName());
        claims.put(CLAIM_KEY_USERID, jwtUserDetail.getUserId());

        return doGenerateToken(jwtUserDetail.getUserId().toString(), claims,expireIn);
    }

    public Integer getUserId(String token){
        Integer userid;
        try {
            final Claims claims = getClaimsFromToken(token);
            userid = claims.get(CLAIM_KEY_USERID, Integer.class);
            if (userid == null) {
                userid = Integer.valueOf(claims.getSubject());
            }
        } catch (Exception e) {
            userid = null;
        }
        return userid;
    }

    public String getTokenType(){
        return tokenType;
    }

    private String  doGenerateToken(String subject,Map<String, Object> claims,long expireIn) {
        return Jwts.builder()
                .setSubject(subject)
                .setClaims(claims)
                .setExpiration(generateExpirationDate(expireIn))
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    private Date generateExpirationDate(long expireIn) {
        return new Date(System.currentTimeMillis() + expireIn);
    }

    private Claims getClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    //.setAllowedClockSkewSeconds(expiration)  //FIXME 临时设置偏离值
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }
}